///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once


#ifndef __DefaultHardwareBufferManager_H__
#define __DefaultHardwareBufferManager_H__

#include "OgrePrerequisites.h"
#include "OgreHardwareBufferManager.h"
#include "OgreHardwareVertexBuffer.h"
#include "OgreHardwareIndexBuffer.h"

namespace Ogre {
	
	

    /// Specialisation of HardwareVertexBuffer for emulation
    class _OgreExport DefaultHardwareVertexBuffer : public HardwareVertexBuffer 
    {
	protected:
		unsigned char* mData;
        
        void* lockImpl(size_t offset, size_t length, LockOptions options);
        
		void unlockImpl(void);
    public:
		DefaultHardwareVertexBuffer(size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage);
		DefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, 
            HardwareBuffer::Usage usage);
        ~DefaultHardwareVertexBuffer();
        
        void readData(size_t offset, size_t length, void* pDest);
        
        void writeData(size_t offset, size_t length, const void* pSource,
				bool discardWholeBuffer = false);
        
        void* lock(size_t offset, size_t length, LockOptions options);
        
		void unlock(void);


    };

	/// Specialisation of HardwareIndexBuffer for emulation
    class _OgreExport DefaultHardwareIndexBuffer : public HardwareIndexBuffer
    {
	protected:
		unsigned char* mData;
        
        void* lockImpl(size_t offset, size_t length, LockOptions options);
        
		void unlockImpl(void);
    public:
		DefaultHardwareIndexBuffer(IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage);
        ~DefaultHardwareIndexBuffer();
        
        void readData(size_t offset, size_t length, void* pDest);
        
        void writeData(size_t offset, size_t length, const void* pSource,
				bool discardWholeBuffer = false);
        
        void* lock(size_t offset, size_t length, LockOptions options);
        
		void unlock(void);

    };

	
	class _OgreExport DefaultHardwareBufferManagerBase : public HardwareBufferManagerBase
	{
    public:
        DefaultHardwareBufferManagerBase();
        ~DefaultHardwareBufferManagerBase();
        /// Creates a vertex buffer
		HardwareVertexBufferSharedPtr 
            createVertexBuffer(size_t vertexSize, size_t numVerts, 
				HardwareBuffer::Usage usage, bool useShadowBuffer = false);
		/// Create a hardware vertex buffer
		HardwareIndexBufferSharedPtr 
            createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, 
				HardwareBuffer::Usage usage, bool useShadowBuffer = false);
		/// Create a hardware vertex buffer
		RenderToVertexBufferSharedPtr createRenderToVertexBuffer();
    };

	/// DefaultHardwareBufferManager as a Singleton
	class _OgreExport DefaultHardwareBufferManager : public HardwareBufferManager
	{
	public:
		DefaultHardwareBufferManager()
			: HardwareBufferManager(PHILO_NEW DefaultHardwareBufferManagerBase()) 
		{

		}
		~DefaultHardwareBufferManager()
		{
			PHILO_DELETE mImpl;
		}
	};

	
	

}

#endif
